<?php

namespace App\Models\CacheModel;

use App\Models\Api\BaseCache;
use think\Log;
use AstroTool\Cache\CacheManage;

/**
 * 合盘结果记录
 */
class AppSynastryResult2021 extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.app_synastry_result_2021';

    protected $cacheModel1 = 'synastry.ranking';
    /**
     * 缓存id键名 为空时不更新
     * @var string
     */
    protected $cacheIdKey = 'id';

    /**
     * 获取合盘分数排行榜列表
     * 只显示20条数据
     * score
     * nickname1 自己档案的昵称
     * nickname2
     * avatar1
     * avatar2
     * relation
     * create_time
     * @throws \Exception
     */
    public function getList()
    {
        // 获取排行榜前100名用户的合盘数据ID集
        $pageData = CacheManage::getInstance()
            ->setCacheConfig($this->cacheModel1)
            ->setPage(1)
            ->setPageSize(100)
            ->setSort('desc')
            ->getListPageDataIds(function ($isCache = true, $sortType = 'desc')
            {
                $resData = $this->getRankingIdsInData();
                if ($isCache)
                {
                    $data = [];
                    foreach ($resData as $uid => $score)
                    {
                        $data[$uid] = ['score' => $score];
                    }
                    return $data;
                }
                return $resData;
            }, 'score', 0);

        $ids = [];// 排行榜前100的ID
        foreach ($pageData['data'] as $uid => $score)
        {
            $score = sprintf("%01.8f", $score);
            $s = explode('.', $score)[1];
            $ids[] = 100000000 - $s;
        }

        $dataList = $this->batchGetInfoByIds($ids, ['score', 'uid', 'nickname1', 'nickname2', 'avatar1', 'avatar2', 'relation', 'create_time']);

        $pageData['data'] = array_values($dataList);

        return $pageData;
    }

    /**
     * 获取用户排行榜排名
     */
    public function userRankingIndex($uid): int
    {
        // 获取排行榜前100名用户的合盘数据ID集
        $pageData = CacheManage::getInstance()
            ->setCacheConfig($this->cacheModel1)
            ->setPage(1)
            ->setPageSize(100)
            ->setSort('desc')
            ->getListPageDataIds(function ($isCache = true, $sortType = 'desc')
            {
                $resData = $this->getRankingIdsInData();
                if ($isCache)
                {
                    $data = [];
                    foreach ($resData as $uid => $score)
                    {
                        $data[$uid] = ['score' => $score];
                    }
                    return $data;
                }
                return $resData;
            }, 'score', 0);

        $uids = array_flip(array_keys($pageData['data']));

        return isset($uids[$uid]) ? $uids[$uid] + 1 : 0;
    }

    /**
     * 开启了缓存
     * @param $ids
     * @param $type
     * @param $sortType
     * @return array|false|string
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        try
        {
            if ($ids)
            {
                $this->whereIn('id', $ids);
            } else
            {
                $this->where('uid', $type[0]);
            }

            $synastryResult = $this->where('status', 1)
                ->order('id ' . $sortType)
                ->column('uid,create_time,update_time,nickname1,nickname2,avatar1,avatar2,score,relation,extra,type,rid1,rid2', 'id');

            foreach ($synastryResult as $id => $item)
            {
                $synastryResult[$id]['order_score'] = $item['update_time'] + ($id / 100000000);
            }
        }
        catch (\Exception $e)
        {
            Log::write('合盘结果获取异常：' . $e->getMessage(), 'error', true);
            return [];
        }

        return $synastryResult;
    }

    /**
     * 获取排行榜前100名用户和分数
     * @return array
     */
    public function getRankingIdsInData()
    {
        try
        {
            return [];
            // 同时有两个相同最大分数时会取多条 bug
            $data = $this->alias('a')->where('score', 'eq', function ($query)
            {
                $query->table('wechat_backup_07_18_14_43_00.app_synastry_result')->where('a.uid=uid')->field('Max(score)');
            })->group('uid')->order('score desc,id asc')->limit(100)->column('id,score', 'uid');

            $resData = [];
            foreach ($data as $uid => $datum)
            {
                $resData[$uid] = $datum['score'] + ((100000000 - $datum['id']) / 100000000);
            }
        }
        catch (\Exception $e)
        {
            return [];
        }

        return $resData;
    }

    /**
     * 保存合盘记录
     * uid int 合盘的用户id
     * share_id int 分享邀请别人填写的档案，表zl_record_share的主键ID
     * create_time bigint 创建时间
     * update_time bigint 更新时间
     * nickname1 varchar(50) 档案1昵称
     * nickname2 varchar(50) 档案2昵称
     * avatar1 string 档案1头像
     * avatar2 string 档案2头像
     * score int 合盘分数
     * relation string 最适合的关系
     * extra json 保存合盘的两个档案信息
     * @param array $data
     * @return bool|int
     */
    public function saveData(array $data = [])
    {
        try
        {
            $id = $this->allowField(true)->insertGetId($data);
        }
        catch (\Exception $e)
        {
            Log::write('合盘记录数据写入错误：' . $e->getMessage(), 'error', true);
            return false;
        }
        return $id;
    }


    /**
     * 获取用户合盘记录
     * @param int $uid
     * @return array|mixed
     * @throws \Exception
     */
    public function getUserList($uid = 0)
    {
        try
        {
            $data = $this
                ->where('uid', $uid)
                ->where('status', 1)
                ->order("id desc")
                ->field('id,create_time,nickname1,nickname2,avatar1,avatar2,score,relation,extra')
                ->select();
        }
        catch (\Exception $e)
        {
            Log::write('合盘结果获取异常：' . $e->getMessage(), 'error', true);
            $data = [];
        }

        return $data;
    }

    /**
     * 没开启缓存
     * @param $uid
     * @param string $sortType
     * @param $page
     * @param $limit
     * @return array|false|string
     */
    public function getUserPaginateInData($uid, $sortType, $page, $limit)
    {
        try
        {
            $synastryResult = $this
                ->where('uid', $uid)
                ->where('status', 1)
                ->order("update_time {$sortType},id {$sortType}")
                ->field('id,create_time,nickname1,nickname2,avatar1,avatar2,score,relation,extra')
                ->paginate($limit, false, ['page' => $page]);
        }
        catch (\Exception $e)
        {
            Log::write('合盘结果获取异常：' . $e->getMessage(), 'error', true);
            return [];
        }

        return $synastryResult;
    }

    /**
     * 获取用户最高分合盘记录
     * @param $uid
     * @return array
     */
    public function getUserHighestScore($uid)
    {
        if ($uid)
        {
            try
            {
                $res = $this
                    ->field('id,nickname1,nickname2,avatar1,avatar2,score,relation')
                    ->where('uid', $uid)
                    ->order('score desc,create_time asc')
                    ->limit(3)
                    ->selectOrFail();

                $res = json_decode(json_encode($res), true);
            }
            catch (\Exception $e)
            {
//                Log::error('获取用户最高合盘分数异常：' . $e->getMessage());
                $res = [];
            }
        } else
        {
            $res = [];
        }

        return $res;
    }
}
